<?php
namespace app\admin\controller;
use app\admin\model\Category;
use app\admin\model\Article as post;
use think\Db;
use think\Config;    //引用模块配置

class Article extends Authentication
{

    //==============
    //1.文章清单列表
    //==============
    public function index()
    {
      try{
        //加载模块配置:默认分页条数
        define("PAGINATE_NUM",config('DEFAULT_PAGINATE_NUM'));

        //实例化模型层对象
        $category = new category;
        
        //查询0以下的所有文章分类,默认选中请选择提示项
        $menu = $category->displayCate(0,0);
        
        //下拉菜单内容为空
        if(""==$menu){
          return $this->error("栏目分类尚未定义");
        }
        //模板参数赋值
        $this->assign('CATEGORY_MENU',$menu);
        
        //通过article表的外键左连接关联查询category表,排序分页输出
        $articles = \think\Db::table('tp_article')->alias('a')->join('category c','a.category = c.id','LEFT')->field('a.id,a.title,c.name_cn as category,a.author,a.status,a.isfeature,a.thumbnail,a.create_time,a.update_time')->paginate(PAGINATE_NUM);

        //模板参数赋值
        $this->assign('ARTICLES',$articles);
        
        return $this->fetch();
      }
      catch(\Exception $e){ //注意异常的捕捉方式
        //var_export($e);
        $msg = $e->getMessage();
        return $this->error('错误提示:文章列表错误'.$msg,url('Article/index'));
      }
    }
    
    //添加方法
    public function insert()
    {
        //加载模块配置参数:文件默认上传路径
        define("UPLOAD_PATH",config('DEFAULT_IMG_UPLOAD_PATH'));
        define("__WWW__",config('__WWW__'));
        //----------------------------------------
        //以下新增文章页面请求处理信息(插入数据库)
        //----------------------------------------
        
        //判断表单是否Post传值
        if(request()->isPost()){
          
          $data=[          
            //@todo 默认文章类型为普通文章
            "category"  =>input("cat_id"),
            "title"     =>input("title"),
            "keywords"  =>input("keywords"),
            "desc"      =>input("desc"),
            "thumbnail" =>input("thumbnail"),
            "content"   =>input("content"),
            "status"    =>input("status"),
            "creator"   =>session('user_name'),
            "create_time"=>date("Y-m-d H:i:s",time()),
            "update_time"=>date("Y-m-d H:i:s",time()),
          ];
          /**
           * 以下:缩略图上传处理
           */
          //判断暂存在服务器上的上传文件临时副本的名称是否存在
          if($_FILES['thumbnail']['tmp_name']){
            
            //获取表单上传文件
            $file = request()->file('thumbnail');
            $image = \think\Image::open($file);             

            //移动到框架应用根目录/public/static/uploads/image目录下,并按日期存储
            $info = $file->move(ROOT_PATH . 'public' . DS . UPLOAD_PATH);
            
            if($info){
                //成功上传后 获取上传信息
                $url = UPLOAD_PATH . date('Y-m-d') . DS . $info->getFilename(); 
                $img = ROOT_PATH . 'public' . $url;
                $today = date("Y-m-d");
                $target = str_replace($today,"thumb/240x160",$img);
                
                //创建目标文件夹
                if(!is_dir(dirname($target))){
                  mkdir(dirname($target), 0777, true);
                }
                //复制文件
                if(copy($img,$target)){
                  
                  // 按照原图的比例生成一个最大240*160的缩略图并保存(替换原图)
                  $res = $image->thumb(240,160,\think\Image::THUMB_FILLED)->save($target);
                  $data['thumbnail'] = str_replace($today,"thumb/240x160",$url);
                }
            }else{
                //上传失败获取错误信息
                return $this->error($file->getError());
            }
          }else{
                //将待发布文章的首图作为缩略图                
                $content=input("content");//获取富文本编辑器内容               
                $info=getPic($content);   //使用函数返回匹配地址
                
                if(!$info==null){
                    $arr = explode("/",$info);
                    $count = count($arr);
                    
                    /*复制图像到规定尺寸的缩略图文件夹*/
                    $arr[$count-2] = 'thumb/240x160';
                    $target = implode("/",$arr);
                    
                    //转换图像地址为绝对路径
                    $info = __WWW__.$info;
                    $target = __WWW__.$target;
                    
                    //创建目标文件夹
                    if(!is_dir(dirname($target))){
                      mkdir(dirname($target), 0777, true);
                    }
                    //复制文件
                    if(copy($info,$target)){
                      
                      //如果复制成功,通过绝对路径创建一个图像对象
                      $image = \think\Image::open($target); 
                      
                      /*生成一个规定尺寸的图像缩略图*/
                      $thumb = $image->thumb(240, 160,\think\Image::THUMB_SCALING)->save($target);
                      $leng = strlen(__WWW__.'/thinkphp5_home/public');
                      $data['thumbnail'] = substr($target,$leng);
                    }
                }else{
                    $thumb='';
                }
          }
          
          //按照规则实例化文章字段验证器
          $validate = \think\Loader::validate('Article');
          
          //验证待插入数据
          if($validate->check($data)){
            
            //插入数据            
            $res = \think\Db::name('Article')->insert($data);
            
            //判断插入结果            
            if($res){
              return $this->success("文章添加成功!",url('Article/index'));
            }else{
              return $this->error("文章添加失败!",url('Article/index'));
            }    
          }else{
            return $this->error($validate->getError());
          }
        }
        
        //--------------------------------------------
        //以下获取文章分类信息并给新增文章模板参数赋值
        //--------------------------------------------
        //实例化模型层对象
        $category = new category;
        
        //查询顶级以下所有文章分类
        $menu = $category->displayCate(0,0);
        
        //模板参数变量替换
        $this->assign('CATEGORY_MENU',$menu);
        
        //如果是添加页面普通加载
        return $this->fetch('insert');

    }
    //==============
    //删除方法(单个)
    //==============
    public function delete()
    {
        //判断表单是否Get传值
        if(request()->isGet()){
          $id = input('id');
          
          // 通过助手函数根据主键删除
          if(Db::name('Article')->delete($id)){
            //return $this->success("文章删除成功!",url('Article/index'));
            show(1, "文章删除成功!");
          }else{
            //return $this->error("文章删除失败!",url('Article/index'));
            show(0, "文章删除失败!");
          }
        }
    }
    //==============
    //删除方法(批量)
    //==============
    public function batch_delete()
    {
        //判断表单是否Post传值
        if(request()->isPost()){
          
          //获取参数
          $id =\think\Request::instance()->param('id'); 
          
          //判断参数是否为空
          if(empty($id)){
            return $this->error("未选择内容");
          }
          
          //非空处理
          $id = join(",",$id);
          
          // 通过助手函数根据主键删除
          if(Db::name('Article')->delete($id)){
            return $this->success("文章批量删除成功!",url('Article/index'));
          }else{
             return $this->error("文章批量删除失败!",url('Article/index'));
          }
        }
    }
    
    //编辑方法
    public function edit()
    {
        //加载模块配置文件:默认文件上传路径参数
        define("UPLOAD_PATH",config('DEFAULT_IMG_UPLOAD_PATH'));
        
        //====================================
        //以下处理表单中用户提交的文章更新信息
        //====================================
        
        //判断表单是否Post传值
        if(request()->isPost()){
          
          //待编辑文档ID
          $id = input('id');
          
          //获取文章更新数据
          $data = [
            'title'=>input('title'),
            'keywords'=>input('keywords'),
            'desc'=>input('desc'),
            'content'=>input('content'),
            'category'=>input('cat_id'),
            'status'=>input('status'),
            'creator'=>session('user_name'),
            'update_time'=>date("Y-m-d H:i:s",time()),
          ];
          //判断暂存在服务器上的文件的临时副本的名称
          if($_FILES['thumbnail']['tmp_name']){
            
            //获取表单上传文件
            $file = request()->file('thumbnail');
            $image = \think\Image::open($file); 
            
            //移动到框架应用根目录/public/static/uploads/image目录下,并按日期存储
            $info = $file->move(ROOT_PATH . 'public' . DS . UPLOAD_PATH);
            
            if($info){
              
                //成功上传后 获取上传信息
                $url = UPLOAD_PATH . date('Y-m-d') . DS . $info->getFilename(); 
                $img = ROOT_PATH . 'public' . $url;
                $today = date("Y-m-d");
                $target = str_replace($today,"thumb/240x160",$img);
                
                //创建目标文件夹
                if(!is_dir(dirname($target))){
                  mkdir(dirname($target), 0777, true);
                }
                //复制文件
                if(copy($img,$target)){
                  
                  // 按照原图的比例生成一个最大240*160的缩略图并保存(替换原图)
                  $res = $image->thumb(240,160,\think\Image::THUMB_SCALING)->save($target);
                  $data['thumbnail'] = str_replace($today,"thumb/240x160",$url);
                }
            }else{
                //上传失败获取错误信息
                return $this->error($file->getError());
            }
          }
          //是否删除缩略图
          if ('1'==input('delete_thumbnail')){
            $data['thumbnail'] = NULL;
          }
          //按照规则实例化验证器
          $validate = \think\Loader::validate('Article');

          //验证器以编辑场景验证待更新数据
          if($validate->scene('edit')->check($data)){

            //更新数据表的数据
            $res = \think\Db::name('Article')
                    ->where('id', $id)
                    ->update($data);
            
            // 判断更新结果        
            if($res){
              return $this->success("文章更新成功!",url('Article/index'));
            }else{
               return $this->error("文章更新失败!",url('Article/index'));
            }
          }else{
            return $this->error($validate->getError());
          }
        }

        //====================================
        //以下加载文章编辑页面
        //====================================
        //判断表单是否Get传值
        if(request()->isGet()){
          
          //获取文章ID
          $id = input('id');
          
          //助手函数查询文章记录
          //注意助手函数和普通数据库类处理的差别
          $article = Db::name('Article')->where('id',$id)->find();
          $this->assign('ARTICLE',$article);
          
          //实例化模型层对象
          $category = new category;
          
          //查询所有文章分类
          $menu = $category->displayCate(0,$article['category']);
          
          //模板参数变量替换
          $this->assign('CATEGORY_MENU',$menu);
          
          //更新页面加载
          return $this->fetch('edit');          
        }
    }
    
    //定义后台文章控制器的分类查询
    public function query($queryID=NULL)
    {
        //加载模块配置参数:默认分页条数
        define("PAGINATE_NUM",config('DEFAULT_PAGINATE_NUM'));
        
        //判断表单是否Post传值
        if(request()->isPost()){
          
          //获取查询参数
          $cat_id = input('cat_id');
          $keywords = input('keywords');
          
          //默认情况下不按照分类查询参数值为false
          $this->assign('QUERY_ALL_UNCATEGORIZED_POST',false);
          
          //参数传回模板文件query.html,希望在更新排序结束之后跳转到该分类列表页面
          $this->assign('CATID',$cat_id);
          
          //如果未选择分类，则按时间倒序分页列出所有文章
          if(0==$cat_id){
            
            //如果是按照关键字查询
            if(''!==trim($keywords)){
              $this->assign('HASKEYWORDS',true);
              
              //通过文章表的外键左连接关联查询分类数据库
              $articles = Db::name('Article')->alias('a')->join('category c','a.category = c.id','LEFT')->field('a.id,a.title,c.name_cn as category,a.author,a.status,a.isfeature,a.thumbnail,a.create_time,a.update_time')->where('a.title', 'like', '%'.$keywords.'%')->paginate(PAGINATE_NUM);
              
            }else{
              $this->assign('HASKEYWORDS',false);
              $this->assign('QUERY_ALL_UNCATEGORIZED_POST',true);
              
              //通过文章表的外键左连接关联查询分类数据库
              $articles = \think\Db::table('tp_article')->alias('a')->join('category c','a.category = c.id','LEFT')->field('a.id,a.title,c.name_cn as category,a.author,a.status,a.isfeature,a.thumbnail,a.create_time,a.update_time')->paginate(PAGINATE_NUM);
            }
          }else{
            
            //如果是按照关键字查询
            if(''!==trim($keywords)){
              $this->assign('HASKEYWORDS',true);
              
              //通过文章表的外键左连接关联查询分类数据库
              $articles = \think\Db::table('tp_article')->alias('a')->join('category c','a.category = c.id','LEFT')->field('a.id,a.title,c.name_cn as category,a.author,a.status,a.isfeature,a.thumbnail,a.create_time,a.update_time')->where('a.category','eq',$cat_id)->where('a.title', 'like', '%'.$keywords.'%')->paginate(PAGINATE_NUM);
              
            }else{
              $this->assign('HASKEYWORDS',false);
              
              //进行分类排序查询,通过文章表的外键左连接关联查询分类数据库
              $articles = \think\Db::table('tp_article')->alias('a')->join('category c','a.category = c.id','LEFT')->field('a.id,a.title,c.name_cn as category,a.author,a.status,a.isfeature,a.thumbnail,a.create_time,a.update_time,a.list_order')->where('a.category','eq',$cat_id)->order('list_order desc')->paginate(PAGINATE_NUM);
            }
          }

          
          //参数变量替换;模板重新加载
          $this->assign('ARTICLES',$articles); 
          
          //实例化模型层对象
          $category = new category;
          
          //查询所有文章分类
          $menu = $category->displayCate(0,$cat_id);
          
          //模板参数变量替换
          $this->assign('CATEGORY_MENU',$menu);
          $this->assign('KEYWORDS',$keywords);
          return $this->fetch("query");
        }else
        {
          return $this->error('查询参数错误',url('Article/index'));
        }
    }

    //更新文章列表排序功能
    public function updateOrder($data){
      try{
          $json = json_decode($data,true);
          $ids = array();
          
          foreach($json as $key=>$value){
            $id = intval($value["name"]);
            $orderId = intval($value["value"]);
            
            $res = \think\Db::name('Article')
                    ->where('id', $id)
                    ->update(['list_order' => $orderId]);
            $ids[]= $res;
          }
          return $this->success('文章排序结束',url('Article/index'));

      }
      catch(\Exception $e){ //注意异常的捕捉方式
        //var_export($e);
        return $this->error('文章列表排序错误',url('Article/index'));
      }      
    }
}